package event

import (
	"gitee.com/jjawesomejj/awesome-util/helper/commonhelper"
	"sync"
)

var eventRegister sync.Map
var callBack sync.Map
var tmpEvent sync.Map
var lock sync.Mutex

func Dispatch(event string, args ...interface{}) {
	if handlers, ok := eventRegister.Load(event); ok {
		for _, handler := range handlers.([]interface{}) {
			if callback, ok := callBack.Load(event); ok {
				go run(event, handler, args, callback.(func(event string, args ...interface{})))
			} else {
				go run(event, handler, args, nil)
			}
		}
	}
}
func run(event string, handler interface{}, args []interface{}, callBack func(event string, args ...interface{})) interface{} {
	defer func() {
		if err := recover(); err != nil {
			commonhelper.PrintStackTrace(err)
			return
		}
	}()
	switch handler.(type) {
	case func(args ...interface{}):
		handler.(func(args ...interface{}))(args...)
		if callBack != nil {
			callBack(event)
		}
		return nil
	case func(args ...interface{}) interface{}:
		res := handler.(func(args ...interface{}) interface{})(args...)
		if callBack != nil {
			callBack(event, res)
		}
		return res
	default:
		return nil
	}
}

/**
同步触发事件同步执行 尽量避免使用
*/
func SyncDispatch(event string, args ...interface{}) interface{} {
	if handlers, ok := eventRegister.Load(event); ok {
		for _, handler := range handlers.([]interface{}) {
			if callback, ok := callBack.Load(event); ok {
				return run(event, handler, args, callback.(func(event string, args ...interface{})))
			} else {
				return run(event, handler, args, nil)
			}
		}
	}
	return nil
}

func Register(event string, handler interface{}) {
	lock.Lock()
	if handlerList, ok := eventRegister.Load(event); ok {
		handlerList = append(handlerList.([]interface{}), handler)
		eventRegister.Store(event, handlerList)
	} else {
		handlerList1 := make([]interface{}, 0)
		handlerList1 = append(handlerList1, handler)
		eventRegister.Store(event, handlerList1)
	}
	lock.Unlock()
}
func RegisterAndCallBack(event string, handler interface{}, callback func(event string, args ...interface{})) {
	Register(event, handler)
	registerCallBack(event, callback)
}
func registerCallBack(event string, callback func(event string, args ...interface{})) {
	callBack.Store(event, callback)
}
func removeCallBack(event string) {
	callBack.Delete(event)
}
func removeEvent(event string) {
	eventRegister.Delete(event)
	callBack.Delete(event)
}

/**
事件注册一次 事件触发一次之后就销毁这个已经注册的事件
*/
func RegisterOne(event string, handler func(args ...interface{})) {
	Register(event, handler)
	registerCallBack(event, func(event string, args ...interface{}) {
		removeEvent(event)
		removeCallBack(event)
	})
}

/**
获取临时事件
*/
func GetTmpEvent(event string) string {
	eventTmp := commonhelper.Rand(10)
	eventName := event + "_" + eventTmp
	tmpEvent.Store(eventName, 1)
	return eventName
}

/**
检查临时事件是否存在
*/
func HasTmpEvent(event string) bool {
	if _, ok := tmpEvent.Load(event); ok {
		tmpEvent.Delete(event)
		return true
	}
	return false
}
